package com.yupi.mianshiya.service.impl;

import cn.hutool.core.collection.CollUtil;
import co.elastic.clients.elasticsearch._types.query_dsl.Like;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yupi.mianshiya.common.DeleteRequest;
import com.yupi.mianshiya.common.ErrorCode;
import com.yupi.mianshiya.common.ResultUtils;
import com.yupi.mianshiya.constant.CommonConstant;
import com.yupi.mianshiya.constant.FavoriteConstant;
import com.yupi.mianshiya.exception.BusinessException;
import com.yupi.mianshiya.exception.ThrowUtils;
import com.yupi.mianshiya.mapper.ArticlesMapper;
import com.yupi.mianshiya.model.dto.articles.ArticleQueryRequest;
import com.yupi.mianshiya.model.entity.*;
import com.yupi.mianshiya.model.vo.ArticlesVO;
import com.yupi.mianshiya.service.ArticlesService;

import com.yupi.mianshiya.service.CommentsService;
import com.yupi.mianshiya.service.FavoriteService;
import com.yupi.mianshiya.service.UserService;
import com.yupi.mianshiya.utils.SqlUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class ArticlesServiceImpl extends ServiceImpl<ArticlesMapper, Articles>
    implements ArticlesService{

    @Resource
    private UserService userService;



    @Resource
    private FavoriteService favoriteService;

    @Resource
    private CommentsService commentsService;

    @Override
    public Wrapper<Articles> getQueryWrapper(ArticleQueryRequest articleQueryRequest) {
        QueryWrapper<Articles> queryWrapper = new QueryWrapper<>();
        if (articleQueryRequest == null) {
            return queryWrapper;
        }

        Long id = articleQueryRequest.getId();
        Long userId = articleQueryRequest.getUserId();
        String title = articleQueryRequest.getTitle();
        String introduction = articleQueryRequest.getIntroduction();
        String sortField = articleQueryRequest.getSortField();
        String sortOrder = articleQueryRequest.getSortOrder();

        //模糊查询
        queryWrapper.like(ObjectUtils.isNotEmpty(title), "title", title);
        queryWrapper.like(ObjectUtils.isNotEmpty(introduction), "introduction", introduction);


        //精确查询
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);

        // 排序规则
        queryWrapper.orderBy(SqlUtils.validSortField(sortField),
                sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);

        return queryWrapper;
    }

    @Override
    public List<ArticlesVO> convertArticlesToVO(List<Articles> articles) {
        if (CollUtil.isEmpty(articles)) {
            return null;
        }
        //使用stream流进行转换
        List<ArticlesVO> articlesVOList = articles.stream()
               .map(ArticlesVO::objToVo)
                .collect(Collectors.toList());
        return articlesVOList;
    }

    @Override
    public void deleteArticle(DeleteRequest deleteRequest, HttpServletRequest request) {

        // 1. 参数校验
        Long articleId = deleteRequest.getId();
        ThrowUtils.throwIf(articleId == null || articleId <= 0, ErrorCode.PARAMS_ERROR, "无效的文章ID");

        // 2. 获取当前登录用户
        User loginUser = userService.getLoginUser(request);
        ThrowUtils.throwIf(loginUser == null, ErrorCode.NOT_LOGIN_ERROR);

        // 3. 获取文章信息
        Articles article = this.getById(articleId);
        ThrowUtils.throwIf(article == null, ErrorCode.NOT_FOUND_ERROR, "文章不存在");

        // 4. 权限验证（仅本人或管理员才能删除）
        if (!loginUser.getId().equals(article.getUserId()) && !userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权删除该文章");
        }

        // 5. 删除文章及相关数据
        ArticlesService articlesService = (ArticlesServiceImpl)AopContext.currentProxy();
        ((ArticlesServiceImpl) articlesService).deleteArticleAndRelatedData(articleId);





    }


    /**
     * 删除文章及所有关联数据
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteArticleAndRelatedData(Long articleId) {
        // 删除文章本身
        boolean articleDeleted = this.removeById(articleId);
        ThrowUtils.throwIf(!articleDeleted, ErrorCode.OPERATION_ERROR, "删除文章失败");

        // 删除文章收藏
        favoriteService.remove(
                new QueryWrapper<Favorite>()
                        .eq("contentId", articleId)
                        .eq("contentType", FavoriteConstant.Article)
        );

        //抛出异常测试事务回滚
//        int i = 1 / 0;

        //删除文章评论
        commentsService.remove(
                new QueryWrapper<Comments>()
                        .eq("articleId", articleId)
        );

        // 删除文章点赞
        // TODO: 待实现




    }


}




